/*
 *  author: Honrun
 */
#include "stdint.h"
#include "stdio.h"
#include "DevicesList.h"
#include "DevicesTime.h"
#include "DevicesSoftTimer.h"



/* 软件定时器状态机的头节点 */
ListType g_typeListSoftTimerHead = {&g_typeListSoftTimerHead, &g_typeListSoftTimerHead, LIST_VALUE_MAX, NULL};



int8_t cSoftTimerSet(SoftTimerTypeDef *ptypeTimer, uint64_t ulTime, SoftTimerStateEnum state)
{
    if(ptypeTimer == NULL)
        return -1;

    ptypeTimer->timeStop = ulSoftTimerGetNow() + ulTime;
    ptypeTimer->timeDuration = ulTime;
    ptypeTimer->state = state;

    return 0;
}

int8_t cSoftTimerReset(SoftTimerTypeDef *ptypeTimer)
{
    if(ptypeTimer == NULL)
        return -1;

    cSoftTimerSet(ptypeTimer, ptypeTimer->timeDuration, ptypeTimer->state | softTimerOpen);

    return 0;
}

int8_t cSoftTimerReload(SoftTimerTypeDef *ptypeTimer)
{
    if(ptypeTimer == NULL)
        return -1;

    ptypeTimer->timeStop += ptypeTimer->timeDuration;
    ptypeTimer->state |= softTimerOpen;

    return 0;
}

int8_t cSoftTimerOpen(SoftTimerTypeDef *ptypeTimer)
{
    if(ptypeTimer == NULL)
        return -1;

    ptypeTimer->state |= softTimerOpen;

    return 0;
}

int8_t cSoftTimerClose(SoftTimerTypeDef *ptypeTimer)
{
    if(ptypeTimer == NULL)
        return -1;

    ptypeTimer->state &= ~softTimerOpen;

    return 0;
}

int8_t cSoftTimerSetState(SoftTimerTypeDef *ptypeTimer, SoftTimerStateEnum enumState)
{
    if(ptypeTimer == NULL)
        return -1;

    if(enumState & softTimerCircular)
        ptypeTimer->state |= softTimerCircular;
    else
        ptypeTimer->state &= ~softTimerCircular;

    return 0;
}

SoftTimerStateEnum enumSoftTimerGetState(SoftTimerTypeDef *ptypeTimer)
{
    int64_t ulTimeNow = 0;

    if(ptypeTimer == NULL)
        return softTimerError;

    if((ptypeTimer->state & softTimerOpen) == 0)
        return softTimerClose;

    ulTimeNow = ulSoftTimerGetNow();

    if(ulTimeNow >= (ptypeTimer->timeStop))
        return softTimerOver;

    return softTimerOpen;
}

/* 单位us */
uint64_t ulSoftTimerGetNow(void)
{
    int64_t lTimeStamp = 0;

    lTimeStamp = lTimeGetStamp();

    return (uint64_t)lTimeStamp;
}







int8_t cSoftTimerCreate(SoftTimerTypeDef *ptypeTimer, uint64_t ulTime, SoftTimerStateEnum state, void (*vCallbackFunction)(void *pvHandle))
{
    int8_t cError = 0;

    if(ptypeTimer == NULL)
        return -1;

    cError |= cSoftTimerSetUs(ptypeTimer, ulTime, state);

    cError |= cListInit(&(ptypeTimer->typeList), ptypeTimer->timeStop);

    /* 按顺序插入 */
    cError |= cListInsert(&g_typeListSoftTimerHead, &(ptypeTimer->typeList));

    ptypeTimer->typeList.pElement = ptypeTimer;

    ptypeTimer->vCallbackFunction = vCallbackFunction;

    return cError;
}

int8_t cSoftTimerRemove(SoftTimerTypeDef *ptypeTimer)
{
    if(ptypeTimer == NULL)
        return -1;

    cListRemove(&(ptypeTimer->typeList));

    return 0;
}

int8_t cSoftTimerMachine(void)
{
    SoftTimerTypeDef *ptypeTimerNow = g_typeListSoftTimerHead.pNext->pElement;
    int8_t cError = 0;

    /* 查询链表第一个元素是否到期 */
    while(enumSoftTimerGetState(ptypeTimerNow) == softTimerOver)
    {
        /* 回调函数 */
        if(ptypeTimerNow->vCallbackFunction != NULL)
        {
            ptypeTimerNow->vCallbackFunction(ptypeTimerNow);
        }

        /* 移出链表 */
        cError |= cListRemove(&(ptypeTimerNow->typeList));

        /* 重复计时 */
        if(ptypeTimerNow->state & softTimerCircular)
        {
            cError |= cSoftTimerReload(ptypeTimerNow);

            cError |= cListInit(&(ptypeTimerNow->typeList), ptypeTimerNow->timeStop);

            /* 按顺序插入 */
            cError |= cListInsert(&g_typeListSoftTimerHead, &(ptypeTimerNow->typeList));
        }
        /* 单次计时 */
        else
            cError |= cSoftTimerClose(ptypeTimerNow);

        /* 把指针再次指令链表第一个元素（第一个元素总是最早到期） */
        ptypeTimerNow = g_typeListSoftTimerHead.pNext->pElement;
    }

    return cError;
}
